/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ig.ejb.metrica.da.session.editor;

import ig.ejb.metrica.da.editor.dao.ColumnaDao;
import ig.ejb.metrica.da.editor.dao.ColumnaOrienDatoDao;
import ig.ejb.metrica.da.editor.dao.TablaDao;
import ig.ejb.metrica.da.editor.dao.abs.DAO;
import ig.ejb.metrica.da.session.editor.dto.ColumnaDTO;
import ig.ejb.metrica.da.session.editor.dto.ColumnaOriegenDatoDTO;
import ig.ejb.metrica.da.session.editor.dto.TablaDTO;
import ig.metrica.ejb.bean.Origenesdatos;
import ig.metrica.ejb.dao.DaoOrigenesdatos;
import ig.metrica.escenario.GenerarEscenariosUtil;
import ig.util.ejb.IGBean;
import java.rmi.RemoteException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 *
 * @author jsanchez
 */
public class EditorSBean  {

    

    
    //----------------------------------------------------------------------
    private List<String> tablas = new ArrayList<String>();

    {
        tablas.add("ACCIONES");
        tablas.add("ACCIONESFLUJOS");
        tablas.add("ACCIONESPOSICIONESFLUJOS");
        tablas.add("ACCIONESVALORES");
        tablas.add("ADICIONALESCONTRATOS");
        tablas.add("CONTRATOSSIMPLES");
        tablas.add("CONTRATOSSIMPLESFLUJOS");
        tablas.add("CONTRATOSSIMPLESTASASPAGO");
        tablas.add("EMISORES");
        tablas.add("EMPRESAS_UNIDADESNEGOCIOS");
        tablas.add("ESPECIES");
        tablas.add("ESPECIESFLUJOS");
        tablas.add("ESPECIESPOSICIONES");
        tablas.add("ESPECIESPOSICIONESFLUJOS");
        tablas.add("ESPECIESTASASPAGO");
        tablas.add("ESPECIESVALORES");
        tablas.add("LIBROS_CUENTAS_PRODUCTOS");
        tablas.add("RELACIONACCIONESSUBCUENTAS");
        tablas.add("RELACIONESPECIESSUBCUENTAS");
        tablas.add("RELACIONMONEDASSUBCUENTAS");
        tablas.add("RELACIONSUBCUENTASPRODUCTOS");
        tablas.add("TASAS");
        tablas.add("TASASVALORES");
        tablas.add("VALORESMONEDAS");
    }
    //----------------------------------------------------------------------

    /**
     * Retorna todas la tablas de la fuente de datos METRICADA
     *
     * @return : LA TABLAS
     * @throws java.lang.Exception
     * @throws java.rmi.RemoteException
     */
    public List<TablaDTO> getAllTables() throws Exception, RemoteException {
        TablaDao dao = new TablaDao();
        ColumnaDao dao1 = new ColumnaDao();
        List<TablaDTO> tablaDTOs = dao.buscarTodos();
        for (TablaDTO tablaDTO : tablaDTOs) {
            tablaDTO.setColumnas(dao1.buscarTodosPorTabla(tablaDTO.getId()));
        }
        for (String tablaStr : tablas) {
            boolean notFound = true;
            for (TablaDTO tablaDTO : tablaDTOs) {
                if (tablaStr.equalsIgnoreCase(tablaDTO.getNombre())) {
                    notFound = false;
                    break;
                }
            }
            if (notFound) {
                tablaDTOs.add(new TablaDTO(null, tablaStr, tablaStr));
            }
        }
        Collections.sort(tablaDTOs);
        return tablaDTOs;
    }

    /**
     * Retorna
     *
     * @param nameTable
     * @return
     * @throws java.lang.Exception
     * @throws java.rmi.RemoteException
     */
    public List<ColumnaDTO> getColumnTables(String nameTable) throws Exception, RemoteException {
        List<ColumnaDTO> columnaDTOs = new ArrayList<ColumnaDTO>();
        Connection connection = null;
        ResultSet resultSet = null;
        TablaDao dao = new TablaDao();
        ColumnaDao dao1 = new ColumnaDao();
        ColumnaOrienDatoDao dao2 = new ColumnaOrienDatoDao();
        try {
            Integer ID = (Integer) dao.existe(nameTable);
            int index = 1;
            connection = IGBean.getMetricaDA();
            //String user = "METRICADA";
            resultSet = connection.getMetaData().getTables(null, null, null, null);
            while (resultSet.next()) {
                if (resultSet.getString(4).trim().equalsIgnoreCase("TABLE") && resultSet.getString(3).trim().equalsIgnoreCase(nameTable)) {
                    ResultSet resultSet1 = connection.getMetaData().getColumns(null, null, resultSet.getString(3).trim(), null);
                    List<String> columnas = new ArrayList<String>();
                    while (resultSet1.next() ) {
                        String nombreColumna = resultSet1.getString(4);
                        if( columnas.contains( nombreColumna.toUpperCase().trim() ) ){
                            continue;
                        }else{
                            columnas.add(nombreColumna.toUpperCase().trim());
                        }
                        int type = resultSet1.getInt(5);
                        if (ID != null && !(Boolean) dao1.existe(new ColumnaDTO(ID, nombreColumna, nombreColumna, 0, 0, 0))) {
                            columnaDTOs.add(new ColumnaDTO(ID, nombreColumna, nombreColumna, type, 0, ++index));
                        } else if (ID == null) {
                            columnaDTOs.add(new ColumnaDTO(ID, nombreColumna, nombreColumna, type, 0, ++index));
                        } else {
                            ColumnaDTO cdto = (ColumnaDTO) dao1.buscar(nombreColumna, ID);
                            cdto.setTipo(type);
                            cdto.setIndex(++index);
                            cdto.setColumnaOriegenDatoDTO((ColumnaOriegenDatoDTO) dao2.buscar(cdto.getId()));
                            columnaDTOs.add(cdto);
                        }
                    }
                    break;
                }
            }
            Collections.sort(columnaDTOs);
        } catch (Exception exception) {
            throw exception;
        } finally {
//            try {
//                connection.close();
//            } catch (Exception e) {
//            }
            try {
                resultSet.close();
            } catch (Exception e) {
            }
        }
        return columnaDTOs;
    }

    /**
     *
     * @param nameTable
     * @return
     * @throws java.lang.Exception
     * @throws java.rmi.RemoteException
     */
    public Map<String, Object> getData(TablaDTO dTO) throws Exception, RemoteException {
        List<Map> list = null;
        Map<String, Object> MAP = new HashMap<String, Object>();
        Map<String, Integer> types = new HashMap<String, Integer>();
        Map<String, Object> oDatos = new HashMap<String, Object>();

        Connection connection = null;
        Statement statement = null;
        try {
            ColumnaDao columnaDao = new ColumnaDao();
            ColumnaOrienDatoDao columnaOrienDatoDao = new ColumnaOrienDatoDao();
            dTO.setColumnas(columnaDao.buscarTodosPorTabla(dTO.getId()));
            Collections.sort(dTO.getColumnas());
            list = new ArrayList<Map>();
            if (dTO.getColumnas().size() <= 0) {
                MAP.put("DATA", list);
                MAP.put("TYPES", types);
                MAP.put("ODATOS", oDatos);                
                return MAP;
            }

            connection = IGBean.getMetricaDA();//new IGBean().getConexion("METRICADA");// DAO.getConnection("METRICADA");
            String QUERY = "";
            for (ColumnaDTO cdto : dTO.getColumnas()) {
                if (cdto.getSeleccion().equals(1) || cdto.getNombre().equalsIgnoreCase("ID")) {
                    if (!QUERY.isEmpty()) {
                        QUERY = QUERY + ", ";
                    }
                    QUERY = QUERY + cdto.getNombre();
                }
                oDatos.put(cdto.getNombre(), columnaOrienDatoDao.buscar(cdto.getId()));
            }
            QUERY = "SELECT " + QUERY + " FROM " + dTO.getNombre().trim().toUpperCase() + " WHERE MANUAL = 1";
            statement = connection.createStatement();
            System.out.println(QUERY);
            ResultSet resultSet = statement.executeQuery(QUERY);
            int columCount = resultSet.getMetaData().getColumnCount();

            for (int i = 1; i <= columCount; i++) {
                String name = resultSet.getMetaData().getColumnName(i);
                Integer type = resultSet.getMetaData().getColumnType(i);
                types.put(name, type);
            }
            while (resultSet.next()) {
                Map<String, Object> map = new HashMap<String, Object>();
                for (int i = 1; i <= columCount; i++) {
                    String name = resultSet.getMetaData().getColumnName(i);
                    Object value = resultSet.getObject(i);
                    map.put(name, value);
                }
                list.add(map);
            }
            MAP.put("DATA", list);
            MAP.put("TYPES", types);
            MAP.put("ODATOS", oDatos);
        } catch (Exception exception) {
            throw exception;
        } finally {
            try {
                statement.close();
            } catch (Exception e) {
            }
//            try {
//                connection.close();
//            } catch (Exception e) {
//            }
        }
        return MAP;
    }

    /**
     *
     * @param nameTable
     * @param fechaCorte
     * @return
     * @throws java.lang.Exception
     * @throws java.rmi.RemoteException
     */
    public List<Map> getData(String nameTable, Timestamp fechaCorte) throws Exception, RemoteException {
        List<Map> list = null;
        Connection connection = null;
        PreparedStatement statement = null;
        try {
            connection = IGBean.getMetricaDA();//new IGBean().getConexion("METRICADA");// DAO.getConnection("METRICADA");
            list = new ArrayList<Map>();

            String QUERY = "SELECT * FROM " + nameTable.trim().toUpperCase() + " WHERE MANUAL = 1 AND FECHA_CORTE = ?";
            statement = connection.prepareStatement(QUERY);
            statement.setTimestamp(1, fechaCorte);
            ResultSet resultSet = statement.executeQuery();
            int columCount = resultSet.getMetaData().getColumnCount();
            while (resultSet.next()) {
                Map<String, Object> map = new HashMap<String, Object>();
                for (int i = 1; i <= columCount; i++) {
                    String name = resultSet.getMetaData().getColumnName(i);
                    Object value = resultSet.getObject(i);
                    map.put(name, value);
                }
                list.add(map);
            }
        } catch (Exception exception) {
            throw exception;
        } finally {
            try {
                statement.close();
            } catch (Exception e) {
            }
//            try {
//                connection.close();
//            } catch (Exception e) {
//            }
        }
        return list;
    }

    private DaoOrigenesdatos daoorigenesdatos = new DaoOrigenesdatos();
    private Origenesdatos origenesdatos  = null;
    private Collection<Object[]> datas = null;        
    private String[] columns = null;    
    /**
     *
     * @param idODato
     * @return
     * @throws java.lang.Exception
     * @throws java.rmi.RemoteException
     */
    public List<Map> getDataODato(ColumnaOriegenDatoDTO coddto, String lLabel, String lValue, int pagina, String filtro ) throws Exception, RemoteException {    
        daoorigenesdatos.setPaginacion(pagina);
        daoorigenesdatos.setFiltro(filtro);
        daoorigenesdatos.setLabel(coddto.getColumna_Label());
        //if ( pagina == 1 ){
        origenesdatos  = daoorigenesdatos.loadById(coddto.getId_ODatos());
        String QUERY=GenerarEscenariosUtil.getQUERY(origenesdatos.getQUERY(),false);
        int ocurrencias = QUERY.replace("_FECHA_CORTE","@").replace("_FECHA_INICIAL","@").split("@").length;
        columns = origenesdatos.getCAMPOS().split(",");
        if ( ocurrencias == 1  &&  !(QUERY.contains("_FECHA_CORTE") || (QUERY.contains("_FECHA_INICIAL"))))  {
            datas = daoorigenesdatos.EjecutarQuery(origenesdatos,new java.sql.Timestamp(new java.util.Date().getTime()).toString());
        }else{
            datas = daoorigenesdatos.EjecutarQuery2(origenesdatos,new java.sql.Timestamp(new java.util.Date().getTime()).toString(),ocurrencias-1,new java.sql.Timestamp(new java.util.Date().getTime()-(1000*60*60*24*365*2)).toString());
        }
        //}
        
        List<Map> list = new ArrayList<Map>();
        for (Object[] data : datas) {
            int i=0;
            Map map = new HashMap();
            for (int j = 0; j < data.length; j++) {
                if(columns.length > i )
                    map.put(columns[i++].trim().toUpperCase(), data[j] );
                else
                    map.put("?"+i, data[j] );
            }
            list.add(map);
        }
        return list;
    }

    /*private static OrigenDeDatos lookupOrigenesDatos(int id) {
        try {
            //Properties prop = new Properties();
            //prop.put( Context.INITIAL_CONTEXT_FACTORY, IGBean.INITIAL_CONTEXT_FACTORY);
            //String Sockec = new ConexionServer().getSocketServer();
            //prop.put( Context.PROVIDER_URL, Sockec);
            //InitialContext ctx = new InitialContext(prop);
            InitialContext ctx = new InitialContext();
            OrigenDeDatosHome home = (OrigenDeDatosHome)ctx.lookup("ig.metrica.origenesdedatos.OrigenDeDatos");
            return home.findByPrimaryKey(new OrigenDeDatosPK(id));
        } catch (FinderException ex) {
            throw new RuntimeException(ex);
        } catch (javax.naming.NamingException ne) {
            throw new RuntimeException(ne);
        } catch (java.rmi.RemoteException re) {
            throw new RuntimeException(re);
        }
    }*/

    /**
     *
     * @param tablaDTO
     * @throws java.lang.Exception
     * @throws java.rmi.RemoteException
     */
    public void update(TablaDTO tablaDTO) throws Exception, RemoteException {
        TablaDao tablaDao = new TablaDao();
        ColumnaDao columnaDao = new ColumnaDao();
        ColumnaOrienDatoDao columnaOrienDatoDao = new ColumnaOrienDatoDao();
        int id = tablaDao.guardar(tablaDTO);
        for (ColumnaDTO dTO : tablaDTO.getColumnas()) {
            dTO.setId_Tabla(id);
            if( dTO.getId()!=null ){
                columnaOrienDatoDao.eliminar( dTO.getId() );
            }
            int idCol = columnaDao.guardar(dTO);
            if( dTO.getColumnaOriegenDatoDTO()!=null ){
                dTO.getColumnaOriegenDatoDTO().setId_Columna(idCol);
                columnaOrienDatoDao.guardar(dTO.getColumnaOriegenDatoDTO());
            }
        }
    }

    /**
     * 
     * @param tablaDTO
     * @throws java.lang.Exception
     * @throws java.rmi.RemoteException
     */
    public void delete(TablaDTO tablaDTO) throws Exception, RemoteException {
        TablaDao tablaDao = new TablaDao();
        ColumnaDao columnaDao = new ColumnaDao();
        ColumnaOrienDatoDao columnaOrienDatoDao = new ColumnaOrienDatoDao();
        Integer ID = (Integer) tablaDao.existe(tablaDTO);
        if (ID != null) {
            List<ColumnaDTO> columnaDTOs = columnaDao.buscarTodosPorTabla(tablaDTO.getId());
            for (ColumnaDTO columnaDTO : columnaDTOs) {
                columnaOrienDatoDao.eliminar(columnaDTO.getId());
                columnaDao.eliminar(columnaDTO.getId());
            }
            tablaDao.eliminar(ID);
        }


    }

    /**
     *
     * @param data
     * @return
     * @throws java.lang.Exception
     * @throws java.rmi.RemoteException
     */
    public int updateRecord(String tabla, String columna, int id, Object data) throws Exception, RemoteException {

        String QUERY = "UPDATE " + tabla.toUpperCase().trim() + " SET " + columna.toUpperCase().trim() + " = ? WHERE ID = ? AND MANUAL = 1";
        Connection connection = null;
        PreparedStatement statement = null;
        try {
            connection = IGBean.getMetricaDA();//new IGBean().getConexion("METRICADA");// DAO.getConnection("METRICADA");
            statement = connection.prepareStatement(QUERY);
            statement.setObject(1, data);
            statement.setInt(2, id);
            return statement.executeUpdate();
        } catch (Exception exception) {
            throw exception;
        } finally {
            try {
                statement.close();
            } catch (Exception e) {
            }
//            try {
//                connection.close();
//            } catch (Exception e) {
//            }
        }

    }

    /**
     * 
     * @param data
     * @param manual
     * @return
     * @throws java.lang.Exception
     * @throws java.rmi.RemoteException
     */
    public int createRecord(String tabla, java.util.Map data) throws Exception, RemoteException {

        String QUERY = "INSERT INTO " + tabla.toUpperCase().trim() + " ( ";
        tabla = tabla.toUpperCase().trim();
        String COLUMNAS = "";
        String VALUES = "";
        Iterator<Map.Entry<String, Object>> iterator = data.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, Object> entry = iterator.next();
            if (!VALUES.trim().isEmpty()) {
                VALUES = VALUES + ", ";
                COLUMNAS = COLUMNAS + ", ";
            }
            VALUES = VALUES + "?";
            COLUMNAS = COLUMNAS + entry.getKey();
        }
        QUERY = "INSERT INTO " + tabla + " ( ID, MANUAL, " + COLUMNAS + " ) VALUES ( ?, 1, " + VALUES + " ) ";

        Connection connection = null;
        PreparedStatement pstatement = null;
        Statement statement = null;
        try {
            connection = IGBean.getMetricaDA();//new IGBean().getConexion("METRICADA");// DAO.getConnection("METRICADA");
            pstatement = connection.prepareStatement(QUERY);
            statement = connection.createStatement();
            iterator = data.entrySet().iterator();
            int index = 1;

            ResultSet resultSet = statement.executeQuery("SELECT MAX(ID) FROM " + tabla);
            resultSet.next();
            Integer ID = resultSet.getInt(1);
            ID = ID != null && !ID.toString().trim().isEmpty() ? Integer.valueOf(ID.toString().trim()) + 1 : 1;
            pstatement.setObject(index++, ID);

            while (iterator.hasNext()) {
                Map.Entry<String, Object> entry = iterator.next();
                Object value = entry.getValue();
                pstatement.setObject(index++, value);
            }
            return pstatement.executeUpdate();
        } catch (Exception exception) {
            throw exception;
        } finally {
            try {
                pstatement.close();
            } catch (Exception e) {
            }
            try {
                statement.close();
            } catch (Exception e) {
            }
//            try {
//                connection.close();
//            } catch (Exception e) {
//            }
        }

    }

    /**
     * 
     * @param data
     * @param manual
     * @return
     * @throws java.lang.Exception
     * @throws java.rmi.RemoteException
     */
    public int deleteRecord(int id, String tabla) throws Exception, RemoteException {

        String QUERY = "DELETE FROM " + tabla.toUpperCase().trim() + " WHERE ID = ?";
        Connection connection = null;
        PreparedStatement statement = null;
        try {
            connection = IGBean.getMetricaDA();//new IGBean().getConexion("METRICADA");// DAO.getConnection("METRICADA");
            statement = connection.prepareStatement(QUERY);
            statement.setInt(1, id);
            return statement.executeUpdate();
        } catch (Exception exception) {
            throw exception;
        } finally {
            try {
                statement.close();
            } catch (Exception e) {
            }
//            try {
//                connection.close();
//            } catch (Exception e) {
//            }
        }
    }
}
